home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
escalant
/
escala21.lha
/
escalante2.1
/
src
/
editor
/
EscalanteCommands.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-15
|
17KB
|
991 lines
//
// Copyright (C) 1993 Jeff McWhirter
//
#include "EscalanteCommands.h"
#include "ET++.h"
#include "EscalanteView.h"
#include "Escalante.h"
#include "VRelation.h"
#include "VEntity.h"
#include "PtGfx.h"
#include "GfxSet.h"
#include "Geometry.h"
#include "ObjectGrid.h"
#include "Dialog.h"
#include "Window.h"
#include "Token.h"
DeleterAdder::~DeleterAdder(){
Iter next(&sset);
Object * o;
while( o= next())
o->RemoveObserver(this);
next.Reset(&vset);
while( o= next())
o->RemoveObserver(this);
}
Command *DeleterAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
SetFlag(eCmdMoveEvents,FALSE);
return this;
}
void DeleterAdder::Init(){
Iter next(&sset);
Object * o;
while( o= next())
o->AddObserver(this);
next.Reset(&vset);
while( o= next())
o->AddObserver(this);
}
void DeleterAdder::DoObserve(int id, int part, void *d , Object *op){
if(op && part == cPartSenderDied) {
sset.Remove(op);
vset.Remove(op);
}
else GraphCommand::DoObserve( id, part,d ,op);
}
void ElementDeleter::DoIt(){
Iter next(&vset);
VGraphElement * vElt;
while(vElt = (VGraphElement*)next())
if(vElt->IsKindOf(VGraphElement))
vElt->SetDead(TRUE);
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next())
if(selt->IsKindOf(SGraphElement))
selt->SetDead(TRUE);
#endif
}
void ElementDeleter::UndoIt(){
Iter next(&vset);
VGraphElement * vElt;
while(vElt = (VGraphElement*)next())
vElt->SetDead(FALSE);
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next())
selt->SetDead(FALSE);
#endif
}
void ElementDeleter::Commit(){
Iter next(&vset);
VGraphElement * vElt;
while(vElt = (VGraphElement*)next()) {
vset.Remove(vElt);
if(vElt->IsDead())
SafeDelete(vElt);
}
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next()) {
sset.Remove(selt);
if(selt->IsDead())
SafeDelete(selt);
}
#endif
}
void EltAdder::DoIt(){
Iter next(&vset);
VGraphElement * velt;
while(velt = (VGraphElement*)next())
velt->SetDead(FALSE);
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next())
selt->SetDead(FALSE);
#endif
}
void EltAdder::UndoIt(){
Iter next(&vset);
VGraphElement * velt;
while(velt = (VGraphElement*)next())
velt->SetDead(TRUE);
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next())
selt->SetDead(TRUE);
#endif
}
void EltAdder::Commit(){SaveElements();}
void EltAdder::SaveElements(){
Iter next(&vset);
VGraphElement * velt;
while(velt = (VGraphElement*)next())
if(!velt->IsDead()) GetVGraphElementSet()->Add(velt);
else {
vset.Remove(velt);
SafeDelete(velt);
}
#ifdef USE_STRUCTURAL
next.Reset(&sset);
SGraphElement * selt;
while(selt = (SGraphElement*)next())
if(!selt->IsDead()) GetSGraphElementSet()->Add(selt);
else {
sset.Remove(selt);
SafeDelete(selt);
}
#endif
}
extern bool gRubberBand;
Command *RectDrawer::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!view) return gNoChanges;
MoverCommand::TrackMouse(tp,ap,pp,np);
Command::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackRelease:
case eTrackExit:
view->DoneDrawingRect();
return gNoChanges;
case eTrackMove:
if(OkToMoveTo(np)){
view->RectDrawn(TRUE);
view->SetSelectionRect(NormalRect(ap,np));
}
default: return this;
}
return this;
}
GroupPicker::GroupPicker(BaseEscalanteView * v,bool newg,Class * c){
view =v;
newgroup = newg;
cl = c;
}
Command *GroupPicker::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!view) return gNoChanges;
Command::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackRelease:
case eTrackExit:
if(view){
if(newgroup)view->SetPickGroup(cl);
else view->AddToPickGroup(cl);
view->RectDrawn(FALSE);
}
return gNoChanges;
case eTrackMove:
if(view){
view->RectDrawn(TRUE);
view->SetSelectionRect(NormalRect(ap,np));
}
return this;
default: return this;
}
return this;
}
Point EscalanteCommand::DoPoint(Point p){
Point np=p;
if(view && view->DoGrid())
np = Point2Grid(p,view->grid);
return (view? Min(view->GetExtent(),np):np);
}
void EscalanteCommand::TrackConstrain(Point ap, Point pp, Point *np){
Command::TrackConstrain( ap, pp, np);
if(np->x <0) np->x = 0;
if(np->y <0) np->y = 0;
if(dopoint)
*np = DoPoint(*np);
}
void JointMover::MoveBy(Point dp){
if(!obj) return;
VGraphElement* elt = (VGraphElement*) obj;
if(doall)elt->AllMoveJointBy(dp,jix);
else elt->MoveJointBy(dp,jix);
gChanged();
}
Command *JointMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!obj) return gNoChanges;
VGraphElement* elt = (VGraphElement*) obj;
MoverCommand::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackExit:
case eTrackRelease:
if(view) view-> DoneMovingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
Point dp;
if(OkToMoveBy(dp,np))
MoveBy(dp);
default: return this;
}
return this;
}
Command *ElementMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
if(!obj) return gNoChanges;
VGraphElement* elt = (VGraphElement*) obj;
MoverCommand::TrackMouse(tp, ap, pp, np);
Point dp;
switch(tp){
case eTrackExit:
case eTrackRelease:
if(view) view-> DoneMovingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
if(OkToMoveBy(dp,np))
MoveBy(dp);
default: return this;
}
return this;
}
void ElementMover::MoveBy(Point dp){
if(!obj) return;
VGraphElement* elt = (VGraphElement*) obj;
if(doall) elt->AllMoveBy(dp);
else elt->MoveBy(dp);
gChanged();
}
Command *QuickMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!obj) return gNoChanges;
VGraphElement* elt = (VGraphElement*) obj;
MoverCommand::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackExit:
if(view) view-> DoneMovingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackRelease:
if(!firstrelease) {firstrelease = TRUE;return this;}
else {
Point dp;
if(OkToMoveBy(dp,np))
MoveBy(dp);
if(view) view-> DoneMovingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
}
default: return this;
}
return this;
}
void QuickMover::MoveBy(Point dp){
if(!obj) return;
VGraphElement* elt = (VGraphElement*) obj;
if(doall) elt->AllMoveBy(dp);
else elt->MoveBy(dp);
gChanged();
}
void MoverCommand::DoObserve(int id, int part, void *d , Object *op){
if(op && op == obj && part == cPartSenderDied) {obj = 0;}
else MultiVCommand::DoObserve( id, part,d ,op);
}
void MoverCommand::DoIt(){
if(doitdelta != gPoint0)
MoveBy(doitdelta);
}
void MoverCommand::UndoIt(){
if(delta != gPoint0)
MoveBy(Point(-delta.x,-delta.y));
doitdelta = delta;
}
bool MoverCommand::OkToMoveBy(Point & deltaP,Point np){
bool r = (Math::Abs(np.x - lastP.x) >1 || Math::Abs(np.y - lastP.y) >1);
if(r){
deltaP = np - lastP;
if(h_or_v && HOrVType == 0) {
if(Math::Abs(deltaP.x) >= Math::Abs(deltaP.y)) HOrVType =1;
else HOrVType =2;
}
if(HOrVType == 1)
deltaP.y =0;
else if(HOrVType == 2)
deltaP.x = 0;
lastP = np;
delta += deltaP;
}
return r;
}
bool MoverCommand::OkToMoveTo(Point& np, int coarseness){
bool r =(Math::Abs(np.x - lastP.x) >coarseness || Math::Abs(np.y - lastP.y) >coarseness);
if(r) {
if(h_or_v && HOrVType == 0) {
if(Math::Abs(np.x-lastP.x) >= Math::Abs(np.y-lastP.y)) HOrVType =1;
else HOrVType =2;
}
if(HOrVType == 1)
np.y =0;
else if(HOrVType==2)
np.x = 0;
delta += np-lastP;
lastP = np;
}
return r;
}
void EltStretcher::MoveBy(Point dp){
if(!obj) return;
VGraphElement* elt = (VGraphElement*) obj;
if(doall)elt->AllReshapeBy(dp,lp,ds);
else elt->ReshapeBy(dp,lp,ds);
gChanged();
}
Command *EltStretcher::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
if(!obj) return gNoChanges;
VGraphElement* elt = (VGraphElement*) obj;
MoverCommand::TrackMouse(tp, ap, pp, np);
Point dp = gPoint0;
switch(tp){
case eTrackRelease:
case eTrackExit:
if(view) view-> DoneMovingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
if(OkToMoveBy(dp,np))
MoveBy(dp);
return this;
default: return this;
}
return this;
}
Command *MoverCommand::TrackMouse(TrackPhase, Point , Point , Point np){
if(!DoneFirst()){
lastP = np;
DoneFirst(TRUE);
}
return gNoChanges;
}
void GfxMover::MoveBy(Point dp){
PtsGfx * gfx = (PtsGfx*) obj;
if(!gfx) return;
gChanged();
gfx->MoveBy(dp);
}
Command *GfxMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!obj) return gNoChanges;
//PtsGfx* gfx = (PtsGfx*) obj;
MoverCommand::TrackMouse(tp, ap, pp, np);
Point dp;
switch(tp){
case eTrackExit:
case eTrackRelease:
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
if(OkToMoveBy(dp,np))
MoveBy(dp);
default:return this;
}
return this;
}
void GfxStretcher::MoveBy(Point dp){
gChanged();
if(!obj) return;
PtsGfx* gfx = (PtsGfx*) obj;
gfx->StretchBy(dp,ptix);
}
Command *GfxStretcher::TrackMouse(TrackPhase tp,Point ap, Point pp, Point np){
if(!obj) return gNoChanges;
//PtsGfx* gfx = (PtsGfx*) obj;
Point dp;
MoverCommand::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackRelease:
case eTrackExit:
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
if(OkToMoveBy(dp,np))
MoveBy(dp);
default:return this;
}
return this;
}
Command *Rotator::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
{
if(!elt) return gNoChanges;
Command::TrackMouse(tp, ap, pp, np);
switch(tp){
case eTrackRelease:
case eTrackExit:
return gNoChanges;
case eTrackPress:
case eTrackMove:
if(doall)elt->AllRotateTo(np);
else elt->RotateTo(np);
gChanged();
return this;
default:return this;
}
return this;
}
RelationAdder::RelationAdder( VRelation * e,VGraphElement * vg,BaseEscalanteView * view ):RelationAdder_BASE(vg,view)
{
SetFlag(eCmdMoveEvents);
SetName("Add relation");
rel = e;
if(view) view->currentElt = rel;
firstrelease = FALSE;
hadrelease = FALSE;
}
Command * RelationAdder::StoppedAdding(){
rel->theimage->SetPickable(TRUE);
if(view) view->currentElt =0;
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElement(rel);
SetFlag(eCmdMoveEvents,FALSE);
return this;
}
Command *RelationAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
VGraphElement * newhd;
if(!rel) return gNoChanges;
if(rel->GetHead() || !rel->NeedHead())
return StoppedAdding();
MoverCommand::TrackMouse(tp,ap,pp,np);
switch(tp){
case eTrackExit:
return StoppedAdding();
case eTrackMove:
if(gRubberBand && OkToMoveTo(np))
rel ->AllSetHdPt(np);
return this;
case eTrackRelease:
hadrelease = TRUE;
firstrelease = TRUE;
return this;
case eTrackPress:
if(!firstrelease) return this;
if(gToken.Code == eEvtMiddleButton) { // Add joint
if(hadrelease){
rel ->AllSetHdPt(np);
rel->AllAddJointLast(np);
}
hadrelease = FALSE;
return this;
}
hadrelease = FALSE;
newhd = rel->GetHead();
if(!newhd && rel->NeedHead()) {
if(view){
gElementOkFunc = view->GetHeadFunc(rel);
view->PickingHd(TRUE);
}
newhd= vgraph->FindClosestElement(np,Meta(VGraphElement),20,view);
if(view) view->PickingHd(FALSE);
gElementOkFunc=0;
if(newhd) rel->SetHead(newhd);
else {
rel ->AllSetHdPt(np);
if(rel->NeedHead() && view) {
ErrorReturn r = view->CouldNotFindHead(rel,&vset);
if( r == eAbort){
view->currentElt =0;
view->PickingTl(FALSE);
return gNoChanges;
}
else if( r == eAbortButSaveElements){
view->currentElt =0;
view->PickingTl(FALSE);
SaveElements();
return gNoChanges;
}
}
}
}
rel->theimage->SetPickable(TRUE);
if(view) view->currentElt =0;
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElement(rel);
SetFlag(eCmdMoveEvents,FALSE);
return this;
default: return this;
}
return this;
}
ElementAdder::ElementAdder( VGraphElement * e,
VGraphElement * vg,
BaseEscalanteView * view ):ElementAdder_BASE(vg,view){
SetFlag(eCmdMoveEvents);
elt = e;
hadrelease =FALSE;
firstrelease = FALSE;
}
Command *ElementAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
if(!elt) return gNoChanges;
if(!elt->NeedJoints()){
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
}
MoverCommand::TrackMouse(tp,ap,pp,np);
switch(tp){
case eTrackExit:
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
case eTrackMove:
if(gRubberBand && OkToMoveTo(np))
elt ->SetP2(np);
return this;
case eTrackRelease:
hadrelease = TRUE;
firstrelease = TRUE;
return this;
case eTrackPress:
if(!firstrelease) return this;
if(gToken.Code == eEvtMiddleButton) { // Add joint
if(hadrelease){
elt ->AllSetP2(np);
elt->AllAddJointLast(np);
}
hadrelease = FALSE;
return this;
}
else {
hadrelease = FALSE;
elt->AllSetP2(np);
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElement(elt);
SetFlag(eCmdMoveEvents,FALSE);
return this;
}
default: return this;
}
return this;
}
EltSetter::EltSetter( VRelation * e,bool tl, VGraphElement * vg,class Class *cl ,BaseEscalanteView * view):EltSetter_BASE(vg,view) {
SetFlag(eCmdMoveEvents);
rel = e;
firstrelease = FALSE;
tail = tl;
c = cl;
if(c == 0) c = Meta(VGraphElement);
if(view) view->currentElt = rel;
}
Command *EltSetter::TrackMouse(TrackPhase tp, Point, Point, Point np){
if(!rel || !vgraph) return gNoChanges;
switch(tp){
case eTrackExit: if(view) view->currentElt =0; return gNoChanges;
case eTrackPress:return this;
case eTrackRelease:
if(!firstrelease) {firstrelease = TRUE;return this;}
if(view) {
if(tail) view->PickingTl(TRUE);
else view->PickingHd(TRUE);
}
VGraphElement * newelt = vgraph->FindClosestElement(np,c,gGravity,view);
if(view) {
if(tail) view->PickingTl(FALSE);
else view->PickingHd(FALSE);
}
if(newelt== 0 ){
if(view){
view->SignalError( "Could not find appropriate element");
view->currentElt =0;
}
return gNoChanges;
}
gChanged();
if(tail) {rel->SetTail(newelt);}
else {rel->SetHead(newelt);}
if(view) view->currentElt =0;
return gNoChanges;
default: return this;
}
return this;
}
MultiAdder::MultiAdder(VGraphElement * e,
VGraphElement * vg,
BaseEscalanteView * view ):MultiAdder_BASE(vg,view){
SetFlag(eCmdMoveEvents);
done =0;
proto = e;
SetFlag(eCmdMoveEvents,FALSE);
}
#define MAXDONE 2000
int doneX[MAXDONE];
int doneY[MAXDONE];
Command *MultiAdder ::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
if(!proto) return gNoChanges;
MoverCommand::TrackMouse(tp,ap,pp,np);
switch(tp){
case eTrackPress:
case eTrackMove:
int i;
for(i=0; (i< done) && (i < MAXDONE); i++)
if(doneX[i] == np.x && doneY[i] == np.y)
return this;
if(gNoRepeatAdd){
ObjectGrid* grid;
if(view && (grid=view->GetGrid()))
if(grid->GetAt( np))
return this;
}
if(done >= MAXDONE) return this;
{
doneX[done] = np.x;
doneY[done++] = np.y;
Set tmpv;
Set tmps;
SetCurrentVGraphElementSet(&tmpv);
#ifdef USE_STRUCTURAL
SetCurrentSGraphElementSet(&tmps);
#endif
gVProtoList = ((EscalanteView*)view)->allprotos;
VEntity * newEntity = (VEntity*)CloneElt(proto,vgraph,gPoint0);
gVProtoList = 0;
SetCurrentVGraphElementSet(0);
#ifdef USE_STRUCTURAL
SetCurrentSGraphElementSet(0);
#endif
{
Iter next(&tmpv);
VGraphElement * tmp;
Object * obj;
while(tmp = (VGraphElement*)next()){
vset.Add(tmp);
tmp->AddObserver(this);
tmp->SetAdding(TRUE);
}
#ifdef USE_STRUCTURAL
next.Reset(&tmps);
while(obj = next()){
obj->AddObserver(this);
sset.Add(obj);
}
#endif
}
gChanged();
newEntity->AllSetOrigin(np);
}
return this;
case eTrackRelease:
case eTrackExit:
{
Iter next(&vset);
VGraphElement * tmp;
while(tmp = (VGraphElement*)next())
tmp->SetAdding(FALSE);
}
if(view)
view->DoneAddingElements(&vset);
return this;
default: return this;
}
return this;
}